package com.gosling.cloudspace.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.payment.facetoface.models.AlipayTradePrecreateResponse;
import com.gosling.cloudspace.common.entity.BaseResult;
import com.gosling.cloudspace.common.entity.dtos.OrderInfoDto;
import com.gosling.cloudspace.common.service.OrderInfoService;
import com.gosling.cloudspace.config.AliPayConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 支付宝支付的实现类
 *
 * @ClassName AliPayServiceImpl
 * @Author @OSC_lihonglin
 * @Date 2021/5/12 23:24
 * @Version 1.0
 */
@Service
public class AliPayServiceImpl {
    protected final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private OrderInfoService orderInfoService;

    /***
     * 支付宝支付-发起付款
     *
     * @param orderInfoDto
     * @return
     */
    public BaseResult nativePay(OrderInfoDto orderInfoDto) {
        // 1. 设置参数（全局只需设置一次）
        Factory.setOptions(AliPayConfig.getAliPayConfig());
        try {
            // 2. 发起API调用（以创建当面付收款二维码为例）
            AlipayTradePrecreateResponse response = Factory.Payment.FaceToFace()
                    .preCreate("Apple iPhone11 128G", "2234567890", "5799.00");
            // 3. 处理响应或异常
            if (ResponseChecker.success(response)) {
                logger.info("调用成功");
            } else {
                logger.error("调用失败，原因：{}.{}", response.msg, response.subMsg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage(), e);
            logger.error("调用遭遇异常，原因：{}", e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
        return null;
    }

    /***
     * 支付宝支付-通用方法
     *
     * @param orderInfoDto
     * @return
     */
    public BaseResult aliTradePay(OrderInfoDto orderInfoDto) {
        try {
            AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", "app_id", "your private_key", "json", "GBK", "alipay_public_key", "RSA2");
            AlipayTradePayRequest request = new AlipayTradePayRequest();
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", "20210817010101001");
            bizContent.put("total_amount", 0.01);
            bizContent.put("subject", "测试商品");
            bizContent.put("scene", "bar_code");
            bizContent.put("auth_code", "28763443825664394");

            // 商品明细信息
            JSONArray goodsDetail = new JSONArray();
            JSONObject goods1 = new JSONObject();
            goods1.put("goods_id", "goodsNo1");
            goods1.put("goods_name", "子商品1");
            goods1.put("quantity", 1);
            goods1.put("price", 0.01);
            goodsDetail.add(goods1);
            bizContent.put("goods_detail", goodsDetail);

            // 扩展信息
            JSONObject extendParams = new JSONObject();
            extendParams.put("sys_service_provider_id", "2088511833207846");
            bizContent.put("extend_params", extendParams);

            // 结算信息
            JSONObject settleInfo = new JSONObject();
            JSONArray settleDetailInfos = new JSONArray();
            JSONObject settleDetail = new JSONObject();
            settleDetail.put("trans_in_type", "defaultSettle");
            settleDetail.put("amount", 0.01);
            settleDetailInfos.add(settleDetail);
            settleInfo.put("settle_detail_infos", settleDetailInfos);
            bizContent.put("settle_info", settleInfo);

            // 二级商户信息
            JSONObject subMerchant = new JSONObject();
            subMerchant.put("merchant_id", "2088000603999128");
            bizContent.put("sub_merchant", subMerchant);

            // 业务参数信息
            JSONObject businessParams = new JSONObject();
            businessParams.put("busi_params_key", "busiParamsValue");
            bizContent.put("business_params", businessParams);

            // 营销信息
            JSONObject promoParams = new JSONObject();
            promoParams.put("promo_params_key", "promoParamsValue");
            bizContent.put("promo_params", promoParams);

            // 返回参数选项
            JSONArray queryOptions = new JSONArray();
            queryOptions.add("fund_bill_list");
            queryOptions.add("voucher_detail_list");
            bizContent.put("query_options", queryOptions);

            request.setBizContent(bizContent.toString());
            AlipayTradePayResponse response = alipayClient.execute(request);
            logger.info("调用结果:{}", response);
            return response.isSuccess() ? BaseResult.success("调用成功") : BaseResult.failed("调用失败");
        } catch (AlipayApiException e) {
            logger.error(e.getMessage(), e);
            e.printStackTrace();
        }
        return BaseResult.failed("调用异常!");
    }

    /***
     * 支付宝支付-设置可选业务参数
     *
     * @param orderInfoDto
     * @return
     */
    public BaseResult alipayParamsBuild(OrderInfoDto orderInfoDto) {
        try {
            List<Object> goodsDetailList = new ArrayList<>();
            Map<String, Object> goodsDetail = new HashMap<>();
            goodsDetail.put("goods_id", "apple-01");
            goodsDetail.put("goods_name", "Apple iPhone11 128G");
            goodsDetail.put("quantity", 1);
            goodsDetail.put("price", "5799.00");
            goodsDetailList.add(goodsDetail);

            Factory.Payment.FaceToFace()
                    // 调用optional扩展方法，完成可选业务参数（biz_content下的可选字段）的设置
                    .optional("seller_id", "2088102146225135")
                    .optional("discountable_amount", "8.88")
                    .optional("goods_detail", goodsDetailList)
                    .preCreate("Apple iPhone11 128G", "2234567890", "5799.00");

            Map<String, Object> optionalArgs = new HashMap<>();
            optionalArgs.put("seller_id", "2088102146225135");
            optionalArgs.put("discountable_amount", "8.88");
            optionalArgs.put("goods_detail", goodsDetailList);

            Factory.Payment.FaceToFace()
                    // 也可以调用batchOptional扩展方法，批量设置可选业务参数（biz_content下的可选字段）
                    .batchOptional(optionalArgs)
                    .preCreate("Apple iPhone11 128G", "2234567890", "5799.00");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return BaseResult.success();
    }
}
